﻿using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
using Neturion.Dados;
using Neturion.IRepositorios;

namespace Neturion.Repositorios
{
    public class RepositorioContaBanco : IRepositorioContaBanco
    {
        public ContaBanco Inserir(ContaBanco contaBanco)
        {
            contaBanco.FimVigencia = contaBanco.FimVigencia.HasValue
                                    ? contaBanco.FimVigencia.GetValueOrDefault().Date
                                    : contaBanco.FimVigencia;
            contaBanco.InicioVigencia = contaBanco.InicioVigencia.HasValue
                                        ? contaBanco.InicioVigencia.GetValueOrDefault().Date
                                        : contaBanco.InicioVigencia;

            GerenciadorBDConfigs.Instance.SessaoAtual().Save(contaBanco);
            return contaBanco;
        }

        public ContaBanco Atualizar(ContaBanco contaBanco)
        {
            ContaBanco tmpContaBanco = ObterPorId(contaBanco.ContaId);
            // Atribuicao dos valores do objeto da memoria para o objeto obtido no banco de dados
            tmpContaBanco.Agencia = contaBanco.Agencia;
            tmpContaBanco.FimVigencia = contaBanco.FimVigencia.HasValue
                                    ? contaBanco.FimVigencia.GetValueOrDefault().Date
                                    : contaBanco.FimVigencia;
            tmpContaBanco.InicioVigencia = contaBanco.InicioVigencia.HasValue
                                        ? contaBanco.InicioVigencia.GetValueOrDefault().Date
                                        : contaBanco.InicioVigencia;
            tmpContaBanco.NeturionLog = contaBanco.NeturionLog;
            tmpContaBanco.SaldoAnterior = contaBanco.SaldoAnterior;
            tmpContaBanco.SaldoAtual = contaBanco.SaldoAtual;
            tmpContaBanco.Limite = contaBanco.Limite;
            tmpContaBanco.PercentualLimite = contaBanco.PercentualLimite;
            tmpContaBanco.TipoContaBanco = contaBanco.TipoContaBanco;
            tmpContaBanco.Titular = contaBanco.Titular;
            tmpContaBanco.NumeroConta = contaBanco.NumeroConta;
            tmpContaBanco.Descricao = contaBanco.Descricao;

            GerenciadorBDConfigs.Instance.SessaoAtual().Merge(tmpContaBanco);
            return tmpContaBanco;
        }

        public void Excluir(ContaBanco contaBanco)
        {
            GerenciadorBDConfigs.Instance.SessaoAtual().Delete(contaBanco);
        }

        public IList<ContaBanco> ObterTodos()
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(ContaBanco));
            return criteria.List<ContaBanco>() as List<ContaBanco>;
        }

        public ContaBanco ObterPorId(int id)
        {
            return GerenciadorBDConfigs.Instance.SessaoAtual().Get<ContaBanco>(id);
        }

        public IList<ContaBanco> ObterPorTipoContaBanco(TipoContaBanco tipoContaBanco)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof (ContaBanco))
                .Add(Restrictions.Eq("TipoContaBanco", tipoContaBanco));
            return criteria.List<ContaBanco>() as List<ContaBanco>;
        }

        public IList<ContaBanco> ObterPorTitular(Pessoa titular)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof (ContaBanco))
                .Add(Restrictions.Eq("Titular", titular));
            return criteria.List<ContaBanco>() as List<ContaBanco>;
        }

        public IList<ContaBanco> ObterPorAgencia(Agencia agencia)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(ContaBanco))
                .Add(Restrictions.Eq("Agencia", agencia));
            return criteria.List<ContaBanco>() as List<ContaBanco>;
        }

        public IList<ContaBanco> ObterPorNumero(string numero, Pessoa titular)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(ContaBanco))
                .Add(Restrictions.Eq("NumeroConta", numero));
            if (titular != null)
            {
                criteria.Add(Restrictions.Eq("Titular", titular));
            }
            return criteria.List<ContaBanco>() as List<ContaBanco>;
        }

        public IList<ContaBanco> ObterTodos(
            string numero,
            TipoContaBanco tipoContaBanco,
            string descricao,
            Agencia agencia,
            Pessoa titular)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(ContaBanco));
            
            if(!string.IsNullOrEmpty(numero))
            {
                criteria.Add(Restrictions.Eq("NumeroConta", numero));
            }

            if(tipoContaBanco != null)
            {
                criteria.Add(Restrictions.Eq("TipoContaBanco", tipoContaBanco));
            }

            if (!string.IsNullOrEmpty(descricao))
            {
                criteria.Add(Restrictions.Eq("Descricao", descricao));
            }

            if (agencia != null)
            {
                criteria.Add(Restrictions.Eq("Agencia", agencia));
            }

            if (titular != null)
            {
                criteria.Add(Restrictions.Eq("Titular", titular));
            }

            return criteria.List<ContaBanco>() as List<ContaBanco>;
        }
    }
}